'''
微信登录模块，用于处理微信登录相关功能，使用wxauto库
'''
import os
import sys
import time
import subprocess
import threading
import pythoncom  # 添加COM支持
from typing import Optional, Callable, Dict, Any

# 在导入wxauto前设置环境变量，禁用wxauto日志
os.environ["WXAUTO_DISABLE_LOGGING"] = "1"
from wxauto import WeChat

from src.utils.config import config_manager
from src.utils.logger import logger

# 禁用wxauto日志，使用我们自己的日志系统
try:
    # 如果wxauto已经创建了日志目录，尝试禁用或重定向
    import logging
    # 设置wxauto的logger级别为ERROR，减少日志输出
    logging.getLogger('wxauto').setLevel(logging.ERROR)
    
    # 获取项目根目录，用于设置日志路径
    if getattr(sys, 'frozen', False):
        # 如果是打包后的可执行文件
        root_dir = os.path.dirname(sys.executable)
    else:
        # 如果是开发环境
        root_dir = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
    
    # 设置wxauto日志目录为我们的日志目录
    logs_dir = os.path.join(root_dir, "logs")
    os.makedirs(logs_dir, exist_ok=True)
    
except Exception as e:
    logger.error(f"配置wxauto日志异常: {e}")


class WeChatLogin:
    """微信登录类，处理微信客户端登录相关功能"""

    def __init__(self):
        """初始化微信登录类"""
        self.wx_instance = None
        self.is_logged_in = False
        self.config = config_manager.get_wechat_config()
        self.login_callback = None
        self.status_check_thread = None
        self.is_running = False
        self.check_interval = 120  # 将初始检查间隔从30秒增加到120秒（2分钟）
        self.login_detected = False  # 是否已检测到登录状态
        self.window_show_count = 0  # 记录显示窗口的次数，用于控制频率
        
    def check_wechat_running(self) -> bool:
        """
        检查微信客户端是否在运行
        
        Returns:
            bool: 微信客户端是否在运行
        """
        try:
            # 初始化COM环境，解决"尚未调用 CoInitialize"错误
            pythoncom.CoInitialize()
            
            # 使用最新的方式获取微信窗口
            wx_instance = WeChat()
            
            # 检查是否成功获取微信窗口
            if wx_instance:
                # 更新实例
                self.wx_instance = wx_instance
                
                # 如果检测到登录，设置标志并增加检查间隔
                if not self.login_detected:
                    self.login_detected = True
                    self.check_interval = 300  # 登录后增加检查间隔到300秒（5分钟），减少窗口检测频率
                    logger.info("已检测到微信登录，减少窗口检测频率")
                
                return True
            else:
                # 如果之前检测到过登录，现在却没检测到，重置状态
                if self.login_detected:
                    self.login_detected = False
                    self.check_interval = 180  # 改为180秒间隔（3分钟），避免过于频繁检测
                    logger.info("微信登录状态丢失，恢复检测频率")
                    self.wx_instance = None
                return False
                
        except Exception as e:
            logger.error(f"检查微信客户端是否在运行异常: {e}")
            # 释放COM环境
            pythoncom.CoUninitialize()
            
            # 发生异常时，设置较长的检查间隔
            self.check_interval = 300
            return False
        finally:
            # 确保释放COM环境
            try:
                pythoncom.CoUninitialize()
            except:
                pass

    def start_wechat(self) -> bool:
        """
        启动微信客户端
        
        Returns:
            bool: 是否成功启动
        """
        try:
            # 微信可能的安装路径，包括D盘
            wechat_paths = [
                os.path.join(os.environ.get('ProgramFiles', 'C:\\Program Files'), 'Tencent\\WeChat\\WeChat.exe'),
                os.path.join(os.environ.get('ProgramFiles(x86)', 'C:\\Program Files (x86)'), 'Tencent\\WeChat\\WeChat.exe'),
                os.path.join(os.environ.get('LOCALAPPDATA', 'C:\\Users\\Administrator\\AppData\\Local'), 'Tencent\\WeChat\\WeChat.exe'),
                os.path.join('D:\\Program Files\\Tencent\\WeChat\\WeChat.exe'),
                os.path.join('D:\\Program Files (x86)\\Tencent\\WeChat\\WeChat.exe'),
                os.path.join('E:\\Program Files\\Tencent\\WeChat\\WeChat.exe'),
                os.path.join('E:\\Program Files (x86)\\Tencent\\WeChat\\WeChat.exe'),
            ]
            
            # 查找微信执行文件
            wechat_exe = None
            for path in wechat_paths:
                if os.path.exists(path):
                    wechat_exe = path
                    logger.info(f"找到微信安装路径: {path}")
                    break
            
            if not wechat_exe:
                logger.error("未找到微信安装路径")
                return False
            
            # 启动微信客户端
            subprocess.Popen(wechat_exe)
            logger.info("正在启动微信客户端...")
            
            # 等待微信启动
            for _ in range(10):
                time.sleep(1)
                if self.check_wechat_running():
                    logger.info("微信客户端已启动")
                    return True
            
            logger.error("微信客户端启动超时")
            return False
        except Exception as e:
            logger.error(f"启动微信客户端异常: {e}")
            return False
        
    def check_login(self) -> bool:
        """
        检查微信是否已登录
        
        Returns:
            bool: 是否已登录
        """
        try:
            # 检查微信客户端是否在运行
            if not self.check_wechat_running():
                logger.error("微信客户端未运行")
                return False
                
            # 在wxauto v2版本中，如果能获取到WeChat实例，则表示已登录
            if self.wx_instance is not None:
                self.is_logged_in = True
                return True
            else:
                self.is_logged_in = False
                return False
                
        except Exception as e:
            logger.error(f"检查微信登录状态异常: {e}")
            self.is_logged_in = False
            return False
            
    def start_status_check(self, login_callback: Optional[Callable] = None):
        """
        启动状态检查线程
        
        Args:
            login_callback: 登录成功回调函数
        """
        self.login_callback = login_callback
        
        if self.status_check_thread and self.status_check_thread.is_alive():
            logger.info("状态检查线程已在运行")
            return
        
        self.is_running = True
        self.status_check_thread = threading.Thread(target=self._status_check_thread)
        self.status_check_thread.daemon = True
        self.status_check_thread.start()
        logger.info("已启动微信状态检查线程")
    
    def stop_status_check(self):
        """停止状态检查线程"""
        self.is_running = False
        if self.status_check_thread and self.status_check_thread.is_alive():
            logger.info("正在停止状态检查线程...")
            self.status_check_thread.join(2)
            logger.info("已停止状态检查线程")
    
    def _status_check_thread(self):
        """状态检查线程"""
        previous_status = False
        check_count = 0
        
        while self.is_running:
            try:
                # 如果已经登录成功，降低检测频率
                if self.login_detected and previous_status:
                    check_count += 1
                    if check_count < 5:  # 增加跳过检测的次数，从3增加到5
                        time.sleep(self.check_interval)
                        continue
                    check_count = 0
                
                current_status = self.check_login()
                
                # 状态发生变化
                if current_status != previous_status:
                    if current_status:
                        logger.info("微信已登录")
                        if self.login_callback:
                            self.login_callback()
                    else:
                        logger.info("微信未登录")
                        # 重置登录检测标志
                        self.login_detected = False
                        self.check_interval = 180  # 从60秒增加到180秒（3分钟）
                    
                    previous_status = current_status
                
                # 根据检查间隔休眠
                time.sleep(self.check_interval)
            except Exception as e:
                logger.error(f"检查微信状态异常: {e}")
                time.sleep(300)  # 发生异常时，将检查间隔从120秒增加到300秒（5分钟）
    
    def ensure_wechat_running(self) -> bool:
        """
        确保微信客户端在运行
        
        Returns:
            bool: 微信是否在运行
        """
        # 检查微信是否在运行
        if self.check_wechat_running():
            return True
        
        # 微信未运行，尝试启动
        return self.start_wechat()
    
    def show_wechat(self) -> bool:
        """
        显示微信窗口
        
        Returns:
            bool: 是否成功显示
        """
        try:
            # 控制显示窗口的频率
            current_time = time.time()
            
            # 确保微信在运行
            if not self.ensure_wechat_running():
                logger.error("无法确保微信在运行")
                return False
            
            # wxauto可能没有ShowWindow方法，使用Win32 API直接操作窗口
            if self.wx_instance:
                try:
                    # 初始化COM环境
                    pythoncom.CoInitialize()
                    
                    # 尝试使用Win32 API直接激活窗口
                    import win32gui
                    import win32con
                    
                    # 获取微信主窗口句柄
                    hwnd = self.wx_instance.GetHandle()
                    if hwnd:
                        # 仅在用户手动触发或特定场景下显示并激活窗口
                        # 检查是否是自动状态检查调用，只有在手动调用时才显示窗口
                        caller_frame = sys._getframe(1)
                        caller_name = caller_frame.f_code.co_name
                        
                        # 手动检查或特定场景才显示窗口
                        if caller_name in ['_check_wechat_status', '_start_monitor', '_check_now', '_send_custom_message']:
                            # 显示并激活窗口
                            win32gui.ShowWindow(hwnd, win32con.SW_RESTORE)
                            win32gui.SetForegroundWindow(hwnd)
                            logger.info(f"已显示微信窗口，调用方法: {caller_name}")
                            return True
                        else:
                            # 自动检查时不显示窗口，只记录日志
                            logger.debug(f"微信窗口存在但不显示，调用方法: {caller_name}")
                            return True
                except Exception as inner_e:
                    logger.error(f"显示微信窗口异常: {inner_e}")
                finally:
                    # 释放COM环境
                    pythoncom.CoUninitialize()
                
            logger.error("无法显示微信窗口")
            return False
        except Exception as e:
            logger.error(f"显示微信窗口异常: {e}")
            return False
    
    def force_logout(self) -> bool:
        """
        强制微信退出登录
        
        Returns:
            bool: 是否成功退出登录
        """
        try:
            # 确保微信在运行
            if not self.ensure_wechat_running():
                logger.error("无法确保微信在运行")
                return False
            
            # 使用Windows API关闭微信窗口
            if self.wx_instance:
                try:
                    # 尝试关闭微信窗口
                    import win32gui
                    import win32con
                    
                    # 获取微信主窗口句柄
                    # 不同版本的wxauto可能有不同的获取句柄的方式
                    hwnd = None
                    
                    # 方法1: 尝试通过handle属性获取
                    if hasattr(self.wx_instance, 'handle'):
                        hwnd = self.wx_instance.handle
                    # 方法2: 尝试通过GetHandle方法获取
                    elif hasattr(self.wx_instance, 'GetHandle'):
                        hwnd = self.wx_instance.GetHandle()
                    # 方法3: 尝试通过hwnd属性获取
                    elif hasattr(self.wx_instance, 'hwnd'):
                        hwnd = self.wx_instance.hwnd
                    
                    # 如果以上方法都失败，尝试通过窗口标题查找
                    if not hwnd:
                        # 尝试获取窗口标题
                        title = None
                        if hasattr(self.wx_instance, 'GetWindowText'):
                            title = self.wx_instance.GetWindowText()
                        
                        if title:
                            # 通过标题查找窗口句柄
                            hwnd = win32gui.FindWindow(None, title)
                    
                    if hwnd:
                        # 发送关闭消息
                        win32gui.PostMessage(hwnd, win32con.WM_CLOSE, 0, 0)
                        logger.info("已发送微信关闭命令")
                        
                        # 重置状态
                        self.wx_instance = None
                        self.is_logged_in = False
                        self.login_detected = False
                        
                        return True
                    else:
                        logger.warning("无法获取微信窗口句柄，尝试其他方式关闭")
                        
                        # 尝试使用Close方法（如果存在）
                        if hasattr(self.wx_instance, 'Close'):
                            self.wx_instance.Close()
                            logger.info("已使用Close方法关闭微信")
                            
                            # 重置状态
                            self.wx_instance = None
                            self.is_logged_in = False
                            self.login_detected = False
                            
                            return True
                except Exception as inner_e:
                    logger.error(f"关闭微信窗口异常: {inner_e}")
            
            logger.error("无法强制退出微信")
            return False
        except Exception as e:
            logger.error(f"强制微信退出登录异常: {e}")
            return False


# 单例实例
wechat_login = WeChatLogin()
